package com.lghdb.driver_client.data;

import org.json.JSONException;
import org.json.JSONObject;

import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by lghdb on 2018/3/23.
 */

public class Model {

    private int uid;
    private String pwd;
    private DataConfig conf;
    private String db;
    private String password;

    public Model(){
        conf = DataConfig.getConfig();
        db = DataConfig.db;
    }

    public <T> Integer count(String model, List<T> where)
            throws DataException{
        Integer objs = (Integer)this.execute(model,
                "search_count", asList(where), null);
        return objs;
    }

    public <T> List<Object> search(String model, List<T> where)
            throws DataException{
        Object[] objs = (Object[])this.execute(model,
                "search", asList(where), null);
        return asList(objs);

    }
    public <T> List<Object> pagination(String model, List<T> where,
                                       final int offset, final int limit)
            throws DataException{
        Object[] objs = (Object[]) this.execute(model, "search",
                asList(where),
                new HashMap<Object, Object>(){{ put("offset", offset); put("limit", limit); }});
        return asList(objs);
    }

    public <T> List<Object> pagination(String model, List<T> where,
                                       final int offset)
            throws DataException{
        return pagination(model, where, offset, 8);
    }

    public <T> List<Object> read(String model, List<T> where,
                                 int offset, String... fields)
            throws DataException{
        return this.read(model, where,offset, 8, fields);
    }
    public <T> List<Object> read(String model, List<T> where,
                                 int offset)
            throws DataException{
        return this.read(model, where,offset, 8);
    }

    public <T> List<Object> read(String model, List<T> where,
                                 int offset,  int limit, String... fields)
            throws DataException{

        Map<Object, Object> select_params = new HashMap<Object, Object>();
        if (fields != null && fields.length > 0){
            select_params.put("fields", fields);
        }
        select_params.put("offset", offset);
        select_params.put("limit", limit);
        Object[] objs = (Object[]) this.execute(model, "search_read",
                asList(where),
                select_params);
        return asList(objs);
    }

    protected  <T> Object execute(String model, String method, List<T> params, Map<Object,Object> kwargs)
            throws DataException{
        Object result = null;
        try{
            if (kwargs == null) {
                result = this.conf.getModel().execute("execute_kw", asList(
                        db, uid, password, model, method, params
                ));
            }else{
                result = this.conf.getModel().execute("execute_kw", asList(
                        db, uid, password, model, method, params, kwargs
                ));
            }
        }catch (Exception e){
            throw new DataException(e);
        }
        return result;
    }


    public <T> Map<String, Map<String, Object>> fields(String model, List<T> where,
                                 String... fields)
            throws DataException{

        Map<Object, Object> select_params = new HashMap<Object, Object>();
        if (fields != null && fields.length > 0){
            select_params.put("attributes", fields);
        }
        Map<String, Map<String, Object>> objs =
                (Map<String, Map<String, Object>>) this.execute(model, "fields_get",
                asList(where),
                select_params);
        return objs;
    }

    public <T> Map<String, Map<String, Object>> fields(String model, String... fields)
            throws DataException{


        return this.fields(model, Collections.emptyList(), fields);
    }

    public int create(String model, Map<String, Object> values)
        throws  DataException{

        return (Integer)this.execute(model,create, asList(values));
    }

    public int login(String username, String pw)
            throws DataException{
        int uid = -1;
        try{
            uid = (int)this.conf.getCommon().execute("authenticate",
                    asList(
                           db, username, pw, emptyList()));
        }catch (Exception e){

        }
        return uid;
    }



    public static void main(String[] args){

        Model model = new Model();
        String pw = "lghdb";
        try{
            int a= model.login("hedb@newhope.cn",pw);
            if (a == -1){
                return;
            }
            model.uid = a;
            model.password = pw;

            List<Object> objs = model.read("res.partner",asList(
                    asList("is_company", "=", false),
                    asList("customer", "=", false)), 0, 20, "display_name"
            );
            for (Object obj : objs){
                HashMap<Object,Object> values = (HashMap<Object,Object>)obj;
                System.out.println(values.get("display_name"));

            }


        }catch (Exception e){
            e.printStackTrace();
        }

    }
}
